package com.rick.demo.mywebsocket.server;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.rick.demo.mywebsocket.entities.Car;
import com.rick.demo.mywebsocket.entities.CarParamDTO;
import com.rick.demo.mywebsocket.entities.Dealer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
@ServerEndpoint("/{openid}/{did}")
public class MyWebSocketServer {

    //    建立一个原子类用于链接计数
    private static AtomicInteger serverCount = new AtomicInteger(0);
    //    建立一个map存放MyWebSocketServer对象,每创建一个连接把自己放进去
    private static ConcurrentHashMap<String, MyWebSocketServer> clients = new ConcurrentHashMap<>();
    //    存放session
    private Session session;
    //
    private CarParamDTO carDto;

    private String keyword;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("openid") String openid, @PathParam("did") String did) {
        this.session = session;
        this.keyword = String.format("%s:%s", openid, did);
        if (clients.containsKey(keyword)) {
            clients.remove(keyword);
            clients.put(keyword, this);
            //加入set中
        } else {
            clients.put(keyword, this);
            //加入set中
            serverCount.incrementAndGet();
            //在线数加1
        }

        log.info("用户连接:" + keyword + ",当前在线人数为:" + serverCount.get());

        try {
            sendMessage("连接成功");
        } catch (Exception e) {
            log.error("用户:" + keyword + ",网络异常!!!!!!");
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:" + keyword + ",报文:" + message);

        //消息保存到数据库、redis
        if (StrUtil.isNotBlank(message)) {
            try {
                if ("ping".equals(message)){
                    sendMessage("pong");
                    return;
                }

                //解析发送的报文
                JSONObject jsonObject = JSONUtil.parseObj(message);
                log.info(jsonObject.toString());
                if (jsonObject.get("contentText").equals("car")) {
                    Car car = new Car();
                    car.setColor("绿色");
                    car.setSize(100);
                    car.setPerson(new ArrayList<String>() {{
                        add("张三");
                        add("rick");
                        add("李四");
                    }});
                    sendMessage(car);
                }

                JSONArray objects = JSONUtil.parseArray(JSONUtil.parseObj(jsonObject.get("contentText")).get("data"));


                List<Dealer> dealers = objects.toList(Dealer.class);

                log.info("dealers金晓尚:{}",dealers);
                sendMessage(dealers);


            } catch (Exception e) {
                sendMessage("数据格式错误");
                e.printStackTrace();
            }
        }
    }


    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if (clients.containsKey(keyword)) {
            clients.remove(keyword);
            //从set中删除
            serverCount.decrementAndGet();
        }
        log.info("用户退出:" + keyword + ",当前在线人数为:" + serverCount.get());
    }

    /**
     * @param error
     */
    @OnError
    public void onError(Throwable error) {
        log.error("用户错误:" + this.keyword + ",原因:" + error.getMessage());
        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(Object message) {
        String s = JSONUtil.toJsonStr(message);
        log.info(s);
        try {
            this.session.getBasicRemote().sendText(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 发送自定义消息
     */
    public static void sendInfo(Object message, String openId, String dId) {
        String keyword = String.format("%s:%s", openId, dId);
        log.info("发送消息到:" + keyword + "，报文:" + message);
        if (StrUtil.isBlank(keyword) && clients.containsKey(keyword)) {
            clients.get(keyword).sendMessage(message);
        } else {
            log.error("用户" + keyword + ",不在线！");
        }
    }

    public static MyWebSocketServer getClient(String openId, String dId) {
        MyWebSocketServer myWebSocketServer = null;
        String keyword = String.format("%s:%s", openId, dId);
        if (StrUtil.isBlank(keyword) && clients.containsKey(keyword)) {
            myWebSocketServer = clients.get(keyword);
        }
        return myWebSocketServer;
    }

    public Session getSession() {
        return session;
    }
}
